package com.qf.blog.controller;

import com.qf.blog.entity.User;
import com.qf.blog.exception.BlogException;
import com.qf.blog.service.impl.FollowerService;
import com.qf.blog.service.IUserService;
import com.qf.blog.service.impl.LikeService;
import com.qf.blog.vo.RepasswordVo;
import com.qf.blog.vo.UserVo;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import javax.servlet.http.HttpSession;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 达哥
 * @since 2023-03-21
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private FollowerService followerService;

    @PostMapping("/register")
    public String register(UserVo userVo) {

        // 1.做校验
        if (ObjectUtils.isEmpty(userVo.getUsername())) {
            throw new BlogException(1001, "用户名不能为空");
        }

        if (ObjectUtils.isEmpty(userVo.getPwd())) {
            throw new BlogException(1001, "密码不能为空");
        }

        // ctrl+x 一次删除一行
        if (ObjectUtils.isEmpty(userVo.getEmail())) {
            throw new BlogException(1001, "邮箱不能为空");
        }

        // 2.实现注册业务
        userService.register(userVo);

        // 3.跳转到一个视图
        return "site/registerSuccess";
    }

    @GetMapping("/activation")
    public String activation(String code) {

        // 1.非空校验
        if (ObjectUtils.isEmpty(code)) {
            throw new BlogException(1001, "code不能为空");
        }

        // 2.根据你的激活码
        Integer status = userService.updateUserStatus(code);
        if (status <= 0) {
            throw new BlogException(1002, "激活有误或者账号已经激活");
        }
        return "redirect:/site/login.html";
    }

    @PostMapping("/login")
    public String login(UserVo userVo, HttpSession session) {

        // 1.数据校验
        if (ObjectUtils.isEmpty(userVo.getUsername())) {
            throw new BlogException(1001, "用户名不能为空");
        }

        if (ObjectUtils.isEmpty(userVo.getPwd())) {
            throw new BlogException(1001, "密码不能为空");
        }

        // 2、根据用户名查询用户
        User user = userService.getUserByUsername(userVo.getUsername());

        if (user == null) {
            throw new BlogException(1002, "用户名不存在");
        }

        // 3.密码的比对
        if (!BCrypt.checkpw(userVo.getPwd(), user.getPassword())) {
            throw new BlogException(1002, "用户名获密码错误");
        }

        // 4.检查账号状态
        if (user.getStatus() != 1) {
            throw new BlogException(1002, "账户未激活");
        }

        // 5.登录成功了
        user.setPassword(null);
        session.setAttribute("loginUser", user); // 把用户信息保存到了session作用域中

        // 6.跳转到首页
        return "redirect:/";
    }

    @GetMapping("/info/{id}")
    public String info(@PathVariable Integer id, Model model, HttpSession session) {

        // 1.根据id查询个人信息
        User user = userService.getById(id);
        user.setPassword(null);

        // 2.查询个人的数据信息(关注量，粉丝量，点赞数量)
        Long follower = followerService.getUserFollowerSize(id);
        Long fans = followerService.getUserFansSize(id);
        Long stars = likeService.getUserLikeNumber(id);
        Boolean hasFollowed = false;

        User loginUser = (User) session.getAttribute("loginUser");
        if (loginUser != null && loginUser.getId() != id) {
            // 再去查询登录用户是否关注点击详情的用户
            hasFollowed=followerService.hasFollower(loginUser.getId(),id);
        }

        // 3.把数据保存到Model中
        model.addAttribute("user", user);
        model.addAttribute("followerCount", follower);
        model.addAttribute("fansCount", fans);
        model.addAttribute("userLikeCount", stars);
        model.addAttribute("hasFollowed", hasFollowed);

        // 4.跳转到首页
        return "site/profile";
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate(); // 注销
        return "redirect:/"; // 重定向到首页
    }

    // 代码QC：代码的质量检查
//    a c d e1 123 遵守代码规范(实战经验的总结)
    @PostMapping("/repass")
    public String repass(RepasswordVo repasswordVo, HttpSession session) {

        // 1.数据校验
        dataValidate(repasswordVo);

        // 2.获取当前登录的用户
        User loginUser = (User) session.getAttribute("loginUser");

        // 3.根据登录用户Id查询密码
        User dbUser = userService.getById(loginUser.getId());

        // 4.对比它的原密码是否正确(明文和密文的对比)
        if (!BCrypt.checkpw(repasswordVo.getOldPassword(), dbUser.getPassword())) {
            throw new BlogException(1003, "原密码不正确");
        }

        // 5.把新密码加密后写入到DB
        String newPwHash = BCrypt.hashpw(repasswordVo.getNewPassword(), BCrypt.gensalt());
        dbUser.setPassword(newPwHash);
        userService.updateById(dbUser);

        // 修改密码成功后需要重新登录
        session.invalidate(); // 注销

        // 6.跳转到首页
        return "redirect:/site/login.html";
    }

    private void dataValidate(RepasswordVo repasswordVo) {
        if (ObjectUtils.isEmpty(repasswordVo.getOldPassword())) {
            throw new BlogException(1001, "密码不能为空");
        }
        if (ObjectUtils.isEmpty(repasswordVo.getNewPassword())) {
            throw new BlogException(1001, "新密码不能为空");
        }
        if (ObjectUtils.isEmpty(repasswordVo.getConfirmPassword())) {
            throw new BlogException(1001, "确认密码不能为空");
        }
        if (!repasswordVo.getConfirmPassword().equals(repasswordVo.getNewPassword())) {
            throw new BlogException(1001, "两次密码不一致");
        }
    }
}